﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using UIFramwork.Pool;
using UIFramwork.Utils;
using UnityEngine;


namespace UIFramwork
{
    /// <summary>
    /// 资产使用库
    /// </summary>
    /// <remarks>
    /// 管理在使用的资产对象
    /// </remarks>
    public class UIAssetsUsed
    {
        public UIAssetsUsed(UIMgr ui)
        {
            m_AssetsUsedLib = new Dictionary<Type, List<UIBase>>();
            m_Root = ui.transform;
        }


        [Description("在用库")] Dictionary<Type, List<UIBase>> m_AssetsUsedLib;
        [Description("根节点")] public readonly Transform m_Root;




        public bool TryGet(Type type,  out UIBase output)
        {
            bool isGet = TryGet(type, out UIBase[] matches);
            if (isGet)
            {
                output = matches[0];
                return this.UseAsSingle(output);
            }
            output = null;
            return false;
        }
        public bool TryGet(Type type, out UIBase[] output)
        {
            bool isGet = m_AssetsUsedLib.TryGetValue(type, out List<UIBase> matches);
            if (!isGet || matches.Count == 0)
            {
                output = null;
                return false;
            }
            output = matches.ToArray();
            return true;
        }


        /// <summary>
        /// 使用|页面实例
        /// </summary>
        public void DoUse(Type type, UIBase uiBase)
        {
            // P1：关旧
            this.UseCloseOld(uiBase);

            // P2：更新实例至缓存中
            this.TryDoCache(type, uiBase);

            uiBase.ActiveUI();


            LayoutUtil.SetQueue(uiBase, this.m_Root);
            LayoutUtil.SetQuard(uiBase);
        }

        /// <summary>
        /// 创建|页面实例
        /// </summary>
        public UIBase DoCreate(Type type)
        {
            GameObject uiObject = UIAssetsPool.GetUnitPool(type).Get();
            UIBase uiBase = uiObject.GetComponent<UIBase>();

            uiBase.StartUI();

            return uiBase;
        }

        /// <summary>
        /// 移除|页面实例
        /// </summary>
        /// <remarks>
        /// 约定： 
        /// <br/>uibase=null = 移除该类型下所有实例页面
        /// <br/>uibase!=null = 移除特定页面实例
        /// </remarks>
        public void DoRemove(Type type, UIBase uiBase = null)
        {
            bool hasType = m_AssetsUsedLib.ContainsKey(type);
            if (!hasType)
            {
                UnityEngine.Debug.LogWarning($"UIAssetsUsed|移除失败|关联资产与类库不匹配：{type} with {uiBase}");
                return;
            }

            UIUnitPool unitPool = UIAssetsPool.GetUnitPool(type);

            if (uiBase == null)
            {
                this.m_AssetsUsedLib[type].ForEach(uiBase =>
                {
                    uiBase.DeActiveUI();

                    unitPool.Recycle(uiBase.gameObject);
                });

                this.m_AssetsUsedLib[type].Clear();
                return;
            }

            uiBase.DeActiveUI();

            unitPool.Recycle(uiBase.gameObject);
   

            this.m_AssetsUsedLib[type].Remove(uiBase);
        }




        private bool TryDoCache(Type type, UIBase uiBase)
        {
            bool hasType = this.m_AssetsUsedLib.ContainsKey(type);
            if (!hasType)
            {
                this.m_AssetsUsedLib.Add(type, new List<UIBase>());
            }

            bool hasUIBase = this.m_AssetsUsedLib[type].Contains(uiBase);
            if (hasUIBase) return false;

            this.m_AssetsUsedLib[type].Add(@uiBase);
            return true;
        }
        private void UseCloseOld(UIBase uiBase)
        {
            if (!uiBase.UseCloseOld) return;

            foreach (var assetUsed in m_AssetsUsedLib)
            {
                if (assetUsed.Value.Count != 0)
                {
                    bool canBeClosed = assetUsed.Value[0].CanBeClosed;
                    if (!canBeClosed) continue;

                    UIUnitPool unitPool = UIAssetsPool.GetUnitPool(assetUsed.Key);

                    assetUsed.Value.ForEach(item =>
                    {
                        if (item.CanBeClosed)
                        {
                            item.DeActiveUI();
                            unitPool.Recycle(item.gameObject);

                            Debug.Log($"<color=red>=====</color> UIAssetsUsed|回收|{assetUsed.Key.Name}");
                        }
                    });

                    assetUsed.Value.Clear();
                }
            }
        }
        private bool UseAsSingle(UIBase uiBase)
        {
            if (!uiBase.UseAsSingle) return false;

            uiBase.transform.SetAsLastSibling();

            return true;
        }
    }
}
